/**
 *  Copyright 2010 Kyle O'Connor, Justin Arling, Mike Mercieca
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package edu.drexel.sd0910.ece01.aqmon.gui.wizard.impl;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

import org.apache.log4j.Logger;

import edu.drexel.sd0910.ece01.aqmon.gui.MainModel;
import edu.drexel.sd0910.ece01.aqmon.gui.wizard.WizardPanelDescriptor;
import edu.drexel.sd0910.ece01.aqmon.manager.xbee.XBeeAutoDetect;

/**
 * Wizard Descriptor - Port Chooser panel. This is the second panel shown during
 * the setup wizard. See
 * {@link edu.drexel.sd0910.ece01.aqmon.gui.wizard.impl.PortChooserPanel
 * PortChooserPanel}.
 * 
 * @author Kyle O'Connor
 * 
 */
public class PortChooserPanelDescriptor extends WizardPanelDescriptor implements ActionListener {

	private final static Logger log = Logger.getLogger(PortChooserPanelDescriptor.class);

	public static final String IDENTIFIER = "PORT_CHOOSER_PANEL";

	private PortChooserPanel panel;
	private String port = null;

	public PortChooserPanelDescriptor(MainModel model) {
		panel = new PortChooserPanel(model);
		this.setPanelIdentifier(IDENTIFIER);
		this.setTargetPanel(panel);
		panel.addDetectPortButtonListener(this);
	}

	@Override
	public void aboutToDisplayPanel() {
		panel.setButtonsEnabled(false); // start them out disabled
		getWizard().setNextFinishButtonEnabled(false);
		getWizard().setBackButtonEnabled(false);
	}

	@Override
	public void aboutToHidePanel() {
		String portInUse;
		if (port == null) {
			portInUse = panel.model.getPortNameFromList(panel.getUserInput());
		} else {
			portInUse = port;
		}
		log.debug(portInUse + " will be used as port.");
		panel.model.setPortName(portInUse);
	}

	@Override
	public void displayingPanel() {
		autoDetectPort();
	}

	@Override
	public Object getBackPanelDescriptor() {
		return WelcomePanelDescriptor.IDENTIFIER;
	}

	@Override
	public Object getNextPanelDescriptor() {
		return NodeDiscoveryPanelDescriptor.IDENTIFIER;
	}

	/**
	 * Find most likely port for XBee device.
	 */
	private void autoDetectPort() {
		log.debug("Attempting to auto detect port");
		new SwingWorker<Void, Void>() {

			boolean found = false;
			String portName = "";

			@Override
			protected Void doInBackground() throws Exception {
				String previousStatus = panel.model.getStatusText();
				panel.model.setStatusText("Auto-detecting XBee port...");

				try {
					portName = new XBeeAutoDetect().getComPort();
					found = true;
					log.debug("XBee Port found as " + portName);
				} catch (Exception e) {
					log.debug(e.getMessage());
					found = false;
				}

				if (found) {
					SwingUtilities.invokeLater(new Runnable() {

						public void run() {
							panel.setResultText("XBee base station device found on port " + portName
									+ ". Press 'Next' to continue.");
							getWizard().setNextFinishButtonEnabled(true);
							getWizard().setBackButtonEnabled(true);
						}
					});
					port = portName;
				} else {
					SwingUtilities.invokeLater(new Runnable() {

						public void run() {
							panel.setResultText("XBee base station device not found. Please make sure the device is connected to the netbook.");
							getWizard().setNextFinishButtonEnabled(true);
							getWizard().setBackButtonEnabled(true);
							panel.setButtonsEnabled(true);
						}
					});
				}
				panel.model.setStatusText(previousStatus);
				return null;
			}
		}.execute();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		panel.setButtonsEnabled(false);
		autoDetectPort();
	}

}
